/**************************************************************************
 * @name: B.c
 * @brief: 模拟云服务器
 * @date: 2025/02/10
 * @author: boluzs@163.com
 * @note: None
 * @version: 1.0.0
 * @Copyright (c) 2025 by boluzs@163.com, All Rights Reserved.
 **************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

#define ABFIFO_PATH "/tmp/abfifo"
#define BCFIFO_PATH "/tmp/bcfifo"

char buf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char captcha[5] = {0};
int abfifo_fd = 0;
int bcfifo_fd = 0;

/**************************************************************************
 * @name: create_code
 * @brief: 创建随机验证码
 * @note:None
 * @retval: None
 **************************************************************************/
void create_code(void)
{
    // 1.生成随机验证码
    srand(time(NULL)); // 生成随机数种子
    for (int i = 0; i < 4; i++)
    {
        captcha[i] = buf[rand() % strlen(buf)];
    }
    printf("生成出来的验证码是：%s\n", captcha);

    // 4.写入到有名管道
    write(bcfifo_fd, captcha, sizeof(captcha));
    // 5.发送信号给进程C
    int n = 0;
    int pid = 0;
    while (n != 1)
    {
        // system("ps aux");
        printf("请输入一个C进程的pid\n");
        n = scanf("%d", &pid);
        kill(pid, SIGUSR1);

        if (n != 1)
            printf("输入的数据类型有误, 请重新输入\n");
        while (getchar() != '\n')
            ;
    }
}

/**************************************************************************
 * @name: check_code
 * @brief: 校验验证码是否正确
 * @note: None
 * @retval: None
 **************************************************************************/
void check_code(void)
{
    // 1.判断是否一致
    printf("check_code_in\n");
    char code[5] = {0};
    read(abfifo_fd, code, sizeof(code));
    printf("code:%s\n", code);
    printf("captcha:%s\n", captcha);
    if (strcmp(code, captcha) == 0)
    {
        printf("匹配成功！\n");
    }
    else
    {
        printf("匹配失败！\n");
    }
}

void signal_handler(int signum)
{
    switch (signum)
    {
    case SIGUSR1:
        create_code();
        break;
    case SIGUSR2:
        check_code();
        break;
    default:
        break;
    }
}

int main(int argc, char const *argv[])
{
    // 1.创建有名管道
    if (access(ABFIFO_PATH, F_OK) == -1) /// tmp/teacher.fifo文件不存在再创建
    {
        if (mkfifo(ABFIFO_PATH, 0666) == -1)
        {
            fprintf(stderr, "[%s] create error,%s\n", ABFIFO_PATH, strerror(errno));
            exit(-1);
        }
    }
    if (access(BCFIFO_PATH, F_OK) == -1) /// tmp/teacher.fifo文件不存在再创建
    {
        if (mkfifo(BCFIFO_PATH, 0666) == -1)
        {
            fprintf(stderr, "[%s] create error,%s\n", BCFIFO_PATH, strerror(errno));
            exit(-1);
        }
    }
    // 2.打开有名管道
    abfifo_fd = open(ABFIFO_PATH, O_RDWR);
    if (abfifo_fd == -1)
    {
        fprintf(stderr, "open [%s] error,%s\n", ABFIFO_PATH, strerror(errno));
        exit(-1);
    }
    // 3.打开有名管道
    bcfifo_fd = open(BCFIFO_PATH, O_RDWR);
    if (bcfifo_fd == -1)
    {
        fprintf(stderr, "open [%s] error,%s\n", BCFIFO_PATH, strerror(errno));
        exit(-1);
    }

    signal(SIGUSR1, signal_handler);
    signal(SIGUSR2, signal_handler);
    // signal(SIGUSR1, create_code);
    // signal(SIGUSR2, check_code);
    for (;;)
        ;
    return 0;
}
